package com.qk.management.web.interceptor;

import com.qk.common.util.CurrentUserContextHolders;
import com.qk.common.util.JwtUtils;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import java.util.Optional;
import java.util.regex.Pattern;

/**
 *
 *
 * @author blusr
 * @version 1.0
 * @date 2025/10/11 15:35
 */
@Slf4j
@Component
@SuppressWarnings("all")
public class LoginCheckInterceptor implements HandlerInterceptor {
    // 局域网IP地址段的正则表达式
    private static final Pattern LAN_IP_PATTERN = Pattern.compile("^(192\\.168\\.|10\\.|172\\.(1[6-9]|2\\d|3[01])\\.)");
    private static final String UNKNOWN = "unknown";

    @Override
    public boolean preHandle(HttpServletRequest request
            , @NonNull HttpServletResponse response
            , @NonNull Object handler) throws Exception {
        // 获取客户端IP地址（针对局域网环境优化）
        String clientIp = getLanClientIpAddress(request);
        log.info("ip: {}", clientIp);

        String token = request.getHeader("token");
        log.info("token: {}", token);
        Optional<String> optional = Optional.ofNullable(token);
        if (optional.isEmpty()) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            return false;
        }
        try {
            Claims claims = JwtUtils.parseToken(optional.get());
            log.info("claims: {}", claims);
            String username = claims.get("username", String.class);
            log.info("username: {}", username);
            Integer userid = claims.get("userid", Integer.class);
            CurrentUserContextHolders.setUserId(userid);
            log.info("userid: {}", userid);
            return true;
        } catch (Exception e) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            return false;
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        CurrentUserContextHolders.clearUserId();
    }

    /**
     * 获取局域网环境下的客户端真实IP地址
     * 优化了在局域网环境中的IP获取逻辑
     */
    private String getLanClientIpAddress(HttpServletRequest request) {
        // 定义要检查的所有可能包含真实IP的请求头
        String[] headerCandidates = {
                "X-Forwarded-For",
                "Proxy-Client-IP",
                "WL-Proxy-Client-IP",
                "HTTP_X_FORWARDED_FOR",
                "HTTP_X_FORWARDED",
                "HTTP_X_CLUSTER_CLIENT_IP",
                "HTTP_CLIENT_IP",
                "HTTP_FORWARDED_FOR",
                "HTTP_FORWARDED",
                "HTTP_VIA",
                "REMOTE_ADDR"
        };

        // 依次检查每个请求头
        for (String header : headerCandidates) {
            String ip = request.getHeader(header);
            if (ip != null && !ip.isEmpty() && !UNKNOWN.equalsIgnoreCase(ip)) {
                // 处理多个IP的情况（多层代理）
                if (ip.contains(",")) {
                    // 分割IP列表，取第一个非unknown的IP
                    String[] ips = ip.split(",");
                    for (String singleIp : ips) {
                        singleIp = singleIp.trim();
                        if (!UNKNOWN.equalsIgnoreCase(singleIp) && isValidIp(singleIp)) {
                            // 如果是局域网IP，直接返回
                            if (isLanIp(singleIp)) {
                                return singleIp;
                            }
                        }
                    }
                    // 如果没有找到局域网IP，返回第一个有效IP
                    if (ips.length > 0) {
                        String firstIp = ips[0].trim();
                        if (!UNKNOWN.equalsIgnoreCase(firstIp) && isValidIp(firstIp)) {
                            return firstIp;
                        }
                    }
                } else {
                    // 单个IP地址
                    ip = ip.trim();
                    if (isValidIp(ip)) {
                        return ip;
                    }
                }
            }
        }

        // 所有请求头都没有找到，使用getRemoteAddr()
        String remoteAddr = request.getRemoteAddr();

        // 处理IPv6本地地址
        if (remoteAddr != null && remoteAddr.contains("0:0:0:0:0:0:0:1")) {
            remoteAddr = "127.0.0.1";
        }

        return remoteAddr;
    }

    /**
     * 验证IP地址格式是否有效
     */
    private boolean isValidIp(String ip) {
        if (ip == null || ip.isEmpty()) {
            return false;
        }

        // IPv4 验证
        String[] parts = ip.split("\\.");
        if (parts.length == 4) {
            try {
                for (String part : parts) {
                    int num = Integer.parseInt(part);
                    if (num < 0 || num > 255) {
                        return false;
                    }
                }
                return true;
            } catch (NumberFormatException e) {
                return false;
            }
        }

        // 简单的IPv6验证
        if (ip.contains(":")) {
            return true; // 简化处理
        }

        return false;
    }

    /**
     * 检查是否为局域网IP地址
     */
    private boolean isLanIp(String ip) {
        return LAN_IP_PATTERN.matcher(ip).find();
    }
}
